Google CalendarのUIを真似てCalendar UIを作る:display: gridを使うver.
frは幅/高さ未指定の子要素の合計幅/高さをfrの合計で割ったもの これで幅/高さを相対指定する
18:06:38 きれいにできた
まだCSSを雑に書き換えた段階なのだが、ずいぶんときれいな見た目になった
DOMも1階層だけでシンプルだ
https://gyazo.com/0211faa19ca30ecfa395dbbb1b99a5f9
18:16:03 CSS調整
思ったより柔軟性あったtakker.icon
18:35:40 終了
配色が見にくいが、後でどうとでもできるので今はいい
https://gyazo.com/1475857edc55708f8ffa21db8ffa2b59
たぶん週表示も、この方法でなんとかなるな
code:grid.tsx
/** @jsx h */
/** @jsxFrag Fragment */
import { h, Fragment } from "../preact/mod.tsx";
import { getAllDaysInCalendar } from "../getAllDaysInCalendar/mod.ts";
import { isToday, getWeek, getDate, getMonth } from "../date-fns/mod.ts";
export const Calendar = ({ onClose }) => {
const weeks = getAllDaysInCalendar(new Date());
const month = getMonth(new Date());
return (<>
<style>{`
:host {
position: fixed;
top: 10%;
left: 10%;
margin: 0 auto;
min-width: 50vw;
min-height: 80vh;
}
.calendar-wrap {
position: absolute;
inset: 0;
outline: none;
overflow: hidden;
height: 100%;
display: grid;
/* row headerの幅を24px固定にし、それ以外を均等に割り振る */
grid-template-columns: 24px repeat(7, 1fr);
/* 何行になるかわからないので、column headerの高さのみ設定しておく */
grid-template-rows: 20px;
/* borderの設定 */
--border: rgb(218,220,224) 1px solid;
* {
border-right: var(--border);
border-bottom: var(--border);
}
:nth-child(-n+8) {
border-top: var(--border);
}
:nth-child(8n+1) {
border-left: var(--border);
}
.header {
background-color: rgb(241,243,244);
color: rgb(60,64,67);
text-align: center;
.column {
text-transform: uppercase;
font-size: 11px;
font-weight: 500;
line-height: 20px;
}
.row {
padding-top: 8px;
font-size: 12px;
font-weight: 500;
letter-spacing: .3px;
line-height: 16px;
}
}
.cell {
font-size: 14px;
line-height: 30px;
text-align: center;
overflow: hidden; /* セルの中身で大きさが変化しなくなる */
h2 {
margin-top: 8px;
font-size: 12px;
font-weight: 500;
letter-spacing: .3px;
display: inline-block;
text-align: center;
white-space: nowrap;
width: max-content;
min-width: 24px;
line-height: 16px;
pointer-events: auto;
}
}
.sun {
}
.sat {
}
.today { background-color: darkblue; }
}
`}</style>
<div className="calendar-wrap" onClick={onClose} role="grid">
<div className="column header corner" />
<div className="column header sun" role="columnheader">日</div>
(day) => (<div className="column header" role="columnheader">{day}</div>)
)}
<div className="column header sat" role="columnheader">土</div>
{weeks.map((dates) => <Week dates={dates} />)}
</div>
</>);
};
const Week = ({ dates }) => (<>
<div className="row header">{getWeek(dates0)}</div> {dates.map((date) => <Cell date={date} />)}
</>);
const Cell = ({ date }) => {
if (isToday(date)) classNames.push("today");
if (date.getDay() === 0) classNames.push("sun");
if (date.getDay() === 6) classNames.push("sat");
if (date.getMonth() !== getMonth(new Date())) classNames.push("mute");
return (
<div className={classNames.join(" ")}>
<h2>{getDate(date) !== 1 ? getDate(date) : ${getMonth(date)}月${getDate(date)}日}</h2>
</div>
);
}